package org.lhl.readruler.manager

import android.content.Intent
import android.net.Uri
import android.os.Environment
import com.blankj.utilcode.util.FileUtils
import com.blankj.utilcode.util.Utils
import io.reactivex.Observable
import org.apache.poi.hssf.usermodel.HSSFRichTextString
import org.apache.poi.xssf.usermodel.XSSFCellStyle
import org.apache.poi.xssf.usermodel.XSSFSheet
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import org.lhl.readruler.bean.DeviceStorage
import org.lhl.readruler.mApp
import java.io.FileOutputStream
import java.text.DecimalFormat
import java.text.SimpleDateFormat
import java.util.*
import kotlin.math.pow

/**
 * Author:  LuoHaoLun
 * Email :  506503279@qq.com
 * Date  :  2020/12/9
 */
const val TYPE_GUIJU_CHAOGAO = 0x00
const val TYPE_CHAZHAO_HUBEI = 0x40
const val TYPE_MAX_MIN = 0x80

object ExcelManager {

    private var defaultCellStyle: XSSFCellStyle? = null
    private var defaultCellHeight: Short = 10

    private val exportDir by lazy { Environment.getExternalStorageDirectory().toString() + "/" }

    fun export(storages: List<DeviceStorage>): Observable<String> {
        return Observable.fromCallable {
            val inputStream = mApp.assets.open("template.xlsx")
            val book = XSSFWorkbook(inputStream)
            val sheets = listOf(book.getSheetAt(0), book.getSheetAt(1))
            defaultCellStyle = sheets[0].getRow(2).getCell(0).cellStyle
            defaultCellHeight = sheets[0].getRow(2).height

            val data = storages.map { it.data }.flatten()
            val data0 = data.filter { it.type and 0xc0 == TYPE_GUIJU_CHAOGAO }
            val data1 = data.filter { it.type and 0xc0 == TYPE_CHAZHAO_HUBEI }
//            val data2 = data.filter { it.type and 0xc0 == TYPE_MAX_MIN }

            val datas = listOf(data0, data1)

            for (j in 0 until 2) {
                val sheet = sheets[j]
                val data = datas[j]
                for ((index, d) in data.withIndex()) {
                    sheet.setContent(2 + index, 0, d.stepIndex)
                    sheet.setContent(2 + index, 1, d.pointIndex)
                    sheet.setContent(2 + index, 2, d.mileage.kps(3))
                    sheet.setContent(2 + index, 3, d.abTrack)
                    sheet.setContent(2 + index, 4, d.d1.kps(2))
                    sheet.setContent(2 + index, 5, d.d2.kps(2))
                }
            }

            val path = "${exportDir}Ruler-${getCurrentTime()}.xlsx"
            val fileOut = FileOutputStream(path)
            book.write(fileOut)
            fileOut.close()
            inputStream.close()
            Utils.getApp().sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(FileUtils.getFileByPath(path))))
            path
        }
    }


    fun XSSFSheet.setContent(row: Int, column: Int, content: Any, cellStyle: XSSFCellStyle? = defaultCellStyle) {
        val row = this.getRow(row) ?: this.createRow(row)
        row.height = defaultCellHeight
        val cell = row.getCell(column) ?: row.createCell(column)
        if (content is HSSFRichTextString)
            cell.setCellValue(content)
        else
            cell.setCellValue(content.toString())
        cell.cellStyle = cellStyle
    }


    fun getCurrentTime(format: String = "MM-dd-HH-mm-ss"): String {
        return SimpleDateFormat(format).format(Date())
    }

}

fun Double.kps(num: Int = 2): String {
    return String.format("%.${num}f", this + 1 / 10.0.pow(num + 1)).let {
        var str = it
        if (str.contains('.'))
            while (str.endsWith('0') || str.endsWith('.')) {
                str = str.removeRange(str.length - 1, str.length)
                if (!str.contains('.'))
                    break
            }
        str
    }
}